#ifndef xpack_lang_cxx_parse
#define xpack_lang_cxx_parse
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::lang_cxx::inc
#include"configure/switch.hpp"
#include"define/base_type.hpp"
#include"define/classify.hpp"
#include"define/nan.hpp"
#include"define/inf.hpp"
#include"lang/cxx/encode_first_as.hpp"
#include"lang/cxx/index_of_first.hpp"
#include"lang/cxx/index_of_first_miss.hpp"
#include"lang/cxx/trim_start.hpp"
#include"lang/cxx.hpp"
#include"macro/xmodify.hpp"
#include"math/numeration_t.hpp"
#include"math/exp10.hpp"
#include"math/exp10r.hpp"
#include"meta/is_base_char.hpp"
#include"meta/is_float.hpp"
#include"meta/is_number.hpp"
#include"math/minimum.hpp"
#include"meta/origin_of.hpp"
#include"meta/unsigned_type.hpp"
#pragma pop_macro("xuser")

namespace mixc::lang_cxx{
    constexpr u08 lut_error = 0xff;
    constexpr u08 lut[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, lut_error, lut_error, lut_error, lut_error, lut_error, lut_error, lut_error, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, lut_error, lut_error, lut_error, lut_error, lut_error, lut_error, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, lut_error, lut_error, lut_error, lut_error, lut_error, };

    template<class item_t, class target_t, class the_t = cxx<item_t>>
    inline parse_result<target_t> parse_core(auto const & self, uxx base_t) {
        bool        is_neg = false;
        target_t    value  = 0;
        item_t *    cur    = (item_t *)self;
        item_t *    begin  = cur;
        item_t *    end    = cur + self->length;

        if (begin >= end) {
            return parse_result<target_t>(value, 0);
        }
        if (cur[0] == '+'){
            cur++;
        }
        else if (cur[0] == '-'){
            cur++;
            is_neg = true;
        }

        if constexpr (inc::is_float<target_t>){
            // 浮点目前只有 10 进制表示
            // inf
            // nan
            // [+-]{0,1}/d*(/./d+){0,1}([eE][+-]/d+){0,1}
            if (the_t{"nan"}.compare({ cur, 3 }) == 0){
                return is_neg ? -target_t(inc::nan) : target_t(inc::nan);
            }
            if (the_t{"inf"}.compare({ cur, 3 }) == 0){
                return target_t(is_neg ? inc::inf_neg : inc::inf_pos);
            }

            auto token          = cur;
            auto token_tmp      = cur;
            auto miss_digital   = false;
            auto miss_decimal   = true;
            auto is_neg_exp     = false;
            auto result         = target_t(0);
            auto mul            = target_t(0.1);
            auto exp            = uxx{};

            auto part = [&](auto value, auto * ptr){
                for(auto & cur = ptr[0]; '0' <= cur[0] and cur[0] <= '9' and cur < end;){
                    value       = value * 10 + cur[0] - '0';
                    cur        += 1;
                };
                return value;
            };

            // skip 0
            while(cur[0] == '0'){
                cur += 1;
            }

            // 得到整数部分
            result              = part(result, xmodify(cur));
            miss_digital        = cur == token;

            // 得到小数部分
            if (cur[0] == '.'){
                cur            += 1;
                token           = cur;
                target_t s      = 0.1;

                while('0' <= cur[0] and cur[0] <= '9' and cur < end){
                    result     += s * (cur[0] - '0');
                    s          *= mul;
                    cur        += 1;
                }
            }

            if (is_neg){
                result          = -result;
            }

            if (miss_decimal = token == cur; not miss_digital or not miss_decimal){
                if (cur == end){
                    return result;
                }

                // 指数部分
                if (cur[0] != 'e' and cur[0] != 'E'){
                    return parse_result<target_t>(result, cur - begin);
                }

                cur            += 1;
                token_tmp       = token = cur;

                if (cur[0] == '-'){
                    cur        += 1;
                    token      += 1;
                    is_neg_exp = true;
                }
                else if (cur[0] == '+'){
                    cur        += 1;
                    token      += 1;
                }

                if (exp = part(exp, xmodify(cur)); token == cur){
                    cur         = token_tmp - 1; // 回滚到字符 'e' or 'E' 之前一个字符
                }
                else if (is_neg_exp){
                    result     *= inc::exp10r<target_t>(exp);
                }
                else{
                    result     *= inc::exp10<target_t>(exp);
                }

                if (cur == end){
                    return result;
                }
            }
            // 如果既没有整数部分，也没有小数部分则表示该字符串不是正确的浮点格式
            else{
                cur             = begin;
            }
            return parse_result<target_t>(result, cur - begin);
        }
        else{
            for(; cur < end; cur++){
                constexpr uxx count = sizeof(lut) / sizeof(lut[0]);

                uxx dis         = uxx(cur[0] - '0');
                uxx v           = lut[dis % count];

                if (dis >= base_t or v == lut_error){
                    break;
                }
                else{
                    value       = value * base_t + v;
                }
            }

            if (is_neg){
                value           = target_t(0) - value;
            }

            // 异常情况
            if (cur != end){
                return parse_result<target_t>(value, cur - begin);
            }
            return value;
        }
    }

    // #define auto  cxx<char>

    inline bstate_t parse_core(auto & self, auto & fmt){
        auto i                  = uxx{};
        auto end                = inc::minimum<uxx>(self->length, fmt->length);

        while(i < end and self[i] == fmt[i]){
            i++;
        }

        self                    = self.backward(i);
        fmt                     = fmt.backward(i);
        return bstate_t::success;
    }

    template<class value_t>
    inline bstate_t parse_core(uxx & parsed_count, auto & self, auto & fmt, value_t && first){
        using origin_t          = inc::origin_of<value_t, with_propcast>; // 如果是属性类型，需要转换一下
        auto skip_list          = { ' ', '\t' };
        fmt                     = fmt.trim_start(skip_list);
        self                    = self.trim_start(skip_list);

        if (self->length == 0u){
            return bstate_t::fail;
        }

        if (fmt->length != 0u){
            if (fmt[0] != '\v'){
                while(true){
                    if (self->length == 0u){
                        return bstate_t::fail;
                    }

                    // 当 fmt[0] 需要匹配参数时或者遇到两者第一个不匹配的字符时退出循环
                    if (fmt[0] == '\v' or fmt[0] != self[0]){
                        break;
                    }

                    fmt         = fmt.backward(1);
                    self        = self.backward(1);
                }
            }
            
            // skip '\v'，可能没有这个
            if (fmt[0] == '\v'){
                fmt             = fmt.backward(1);
            }
        }

        if constexpr (inc::is_base_char<origin_t>){
            auto item           = self.template encode_first_as<origin_t>();
            self                = self.backward(item->skip_to_next);
            first               = item;
        }
        else if constexpr (inc::is_number<origin_t>){
            if (auto value = self.template parse<origin_t>(); value->is_parsed_nothing){
                return bstate_t::fail;
            }
            else{
                first           = value;
                self            = self.backward(value->is_parsed_completely ? self->length : value->index_of_error);
            }
        }
        else if constexpr (inc::is_cxx<origin_t>){
            if (auto i_miss = self.index_of_first_miss(skip_list); i_miss == not_exist){
                self            = self.backward(self->length);
            }

            // fmt[0]   : 'A'
            // self     : xxxxA...
            //                ^
            // 匹配到 fmt[0] 所表示的终结符时停止匹配
            auto skip_listx     = { fmt[0] };
            auto select         = fmt->length != 0u and fmt[0] != '\v';
            auto i_end          = self.index_of_first(select ? skip_listx : skip_list);

            if (first = self; i_end != not_exist){
                first->length   = i_end;
                self            = self.backward(i_end + 1); // 顺便跳过终结符

                if (fmt->length){
                    fmt         = fmt.backward(1);
                }
            }
            else{
                first->length   = self->length;
                self            = self.backward(self->length); // 没匹配到终结符
            }
        }
        else{
            static_assert(inc::is_base_char<origin_t>);
            return bstate_t::fail;
        }

        parsed_count           += 1;
        return bstate_t::success;
    }

    template<class item_t>
    template<class target_t>
    inline parse_result<target_t> cxx<item_t>::parse() const {
        return parse_core<item_t, target_t>(xthe, 10);
    }

    template<class item_t>
    template<class target_t>
    requires(inc::is_float<target_t> == false)
    inline parse_result<target_t> cxx<item_t>::parse(inc::numeration_t raidx) const {
        if constexpr (sizeof(target_t) <= sizeof(uxx)){
            return parse_core<item_t, target_t>(xthe, uxx(raidx));
        }
        else{
            return parse_core<item_t, inc::unsigned_type<target_t>>(xthe, uxx(raidx));
        }
    }

    template<class item_t>
    template<class first_t, class ... rest_t>
    inline parse_result<uxx> cxx<item_t>::parse_list(the_cref_t fmt, first_t && first, rest_t && ... rest) const {
        // 使用临时变量，避免直接修改 xthe 和 fmt
        auto temp_self          = xthe;
        auto temp_fmt           = fmt;
        auto parsed_count       = uxx{};
        
        // 使用折叠表达式减少递归深度
        (parse_core(parsed_count, temp_self, temp_fmt, ((first_t &&)first))) and
        (... and parse_core(parsed_count, temp_self, temp_fmt, ((rest_t &&)rest))) and
        (parse_core(temp_self, temp_fmt));

        if (temp_self->length == 0u and temp_fmt->length == 0u){
            return parse_result<uxx>{ parsed_count };
        }
        // 可能 temp_self 已经匹配完成，但是 fmt 没有匹配完成
        else{
            return parse_result<uxx>{ parsed_count, xthe->length - temp_self->length };
        }
    }
}

#endif
